#include "cgzCLua.h"
#include "cgzCTcpGateWS.h"
#include "cgzCThreadPool.h"

static int bind(lua_State *L)
{
    // 将其转换为 cgzCLua 指针
    cgzCLua *that = cgzCLua::getThat(L);
    const char *name = lua_tostring(L, 1);
    const char *ip = lua_tostring(L, 2);
    int port = lua_tointeger(L, 3);
    bool gate = lua_toboolean(L, 4);
    int tref = luaL_ref(L, LUA_REGISTRYINDEX);
    void *node = malloc(sizeof(cgzCTcpGateWS));
    int cid = that->getId();
    auto ctcp = new (node) cgzCTcpGateWS(that->m_pool, name, ip, port, cid, gate);
    ctcp->m_tref = tref;
    ctcp->tcpbind();
    lua_pushinteger(L, ctcp->getId());
    return 1;
}

static int send(lua_State *L)
{
    // 将其转换为 cgzCLua 指针
    cgzCLua *that = cgzCLua::getThat(L);
    const char *name = lua_tostring(L, 1);
    const int gfd = lua_tointeger(L, 2);
    const int cfd = lua_tointeger(L, 3);
    const int mid = lua_tointeger(L, 4);
    size_t len = 0;
    const char *pck = lua_tolstring(L, 5, &len);
    int all = len + sizeof(cgzGateHeader);
    // 添加消息头
    auto buffer = (char *)malloc(all);
    auto &header = *(cgzGateHeader *)(buffer);
    header.mid = mid;
    header.len = len;
    header.all = all;
    header.ufd = cfd;
    header.cid = luaL_checkinteger(L, 6);
    // 拷贝内容
    memcpy(buffer + sizeof(cgzGateHeader), pck, len);
    void *node = malloc(sizeof(cgzCSendWS));
    auto psend = new (node) cgzCSendWS(gfd, buffer, all, WEBSOCKET_SEND_BINARY);
    that->regTask(name, psend);
    free(buffer);
    return 0;
}

static int forward_add(lua_State *L)
{
    // 将其转换为 cgzCLua 指针
    cgzCLua *that = cgzCLua::getThat(L);
    const char *name = lua_tostring(L, 1);
    void *node = malloc(sizeof(cgzCGAddS));
    auto pCmd = new (node) cgzCGAddS();
    lua_pushnil(L);
    while (lua_next(L, -2))
    {
        int mid = lua_tointeger(L, -2);
        int tid = lua_tointeger(L, -1);
        pCmd->map[mid] = tid;
        lua_pop(L, 1);
    }
    that->regTask(name, pCmd);
    return 0;
}

static int forward_del(lua_State *L)
{
    // 将其转换为 cgzCLua 指针
    cgzCLua *that = cgzCLua::getThat(L);
    const char *name = lua_tostring(L, 1);
    void *node = malloc(sizeof(cgzCGDelS));
    auto pCmd = new (node) cgzCGDelS();
    lua_pushnil(L);
    while (lua_next(L, -2))
    {
        int mid = lua_tointeger(L, -2);
        pCmd->set.insert(mid);
        lua_pop(L, 1);
    }
    that->regTask(name, pCmd);
    return 0;
}

static int forward_cls(lua_State *L)
{
    // 将其转换为 cgzCLua 指针
    cgzCLua *that = cgzCLua::getThat(L);
    const char *name = lua_tostring(L, 1);
    void *node = malloc(sizeof(cgzCGClrS));
    auto pCmd = new (node) cgzCGClrS();
    that->regTask(name, pCmd);
    return 0;
}

int cgzCLua::luaopen_tcpGateWS(lua_State *L)
{
    static const luaL_Reg otherlib[] = {
        {"bind", bind},
        {"send", send},
        {"forward_add", forward_add},
        {"forward_del", forward_del},
        {"forward_cls", forward_cls},
        {NULL, NULL}};

    luaL_newlib(L, otherlib);
    return 1;
}